#include "UltimatePhysX3Precompiled.h"
#include "UltimatePhysX3Actor.h"


UltimatePhysX3Actor::UltimatePhysX3Actor(void)
{
	kinematic = false;
}


UltimatePhysX3Actor::~UltimatePhysX3Actor(void)
{
}

void UltimatePhysX3Actor::setPxActor(PxRigidDynamic* actor)
{
	nxActor = actor;
}

PxActor* UltimatePhysX3Actor::getPxActor()
{
	return nxActor;
}


void UltimatePhysX3Actor::setGlobalPosition(Ogre::Vector3 position)
{
	PxTransform newPose;

	PxTransform pose= nxActor->getGlobalPose();
	
	newPose.p = PxVec3(position.x, position.y , position.z);
	newPose.q = pose.q;

	setPose(newPose);

}

Ogre::Vector3 UltimatePhysX3Actor::getGlobalPosition()
{
	PxTransform pose= nxActor->getGlobalPose();

	return Ogre::Vector3(pose.p.x, pose.p.y, pose.p.z);
}

void UltimatePhysX3Actor::setGlobalOrientation(Ogre::Quaternion orientation)
{
	PxTransform newPose;

	PxTransform pose= nxActor->getGlobalPose();
	
	newPose.q = PxQuat(orientation.x,orientation.y,orientation.z,orientation.w);
	newPose.p = pose.p;

	setPose(newPose);

}

Ogre::Quaternion UltimatePhysX3Actor::getGlobalOrientation()
{
	PxTransform pose= nxActor->getGlobalPose();
	return Ogre::Quaternion(pose.q.w, pose.q.x, pose.q.y,pose.q.z);
}



void UltimatePhysX3Actor::setLookAt(Ogre::Vector3 target)
{

	PxTransform newPose;

	PxTransform pose= nxActor->getGlobalPose();

	PxQuat initOri = pose.q;
	PxVec3 initDir = initOri.rotate(PxVec3(1,0,0));

	initDir.normalize();

	PxVec3 dir =PxVec3(target.x,target.y,target.z)- pose.p;
	dir.normalize();

	PxVec3 axis = initDir.cross(dir);
	float cosAng = initDir.dot(dir);
		

	float ang = acos(cosAng);
	Ogre::Radian radian = Ogre::Radian(ang);
	float angDeg = radian.valueDegrees();

	PxQuat newRot = PxQuat(angDeg , axis);
	newPose.q = newRot*initOri;
	newPose.p = pose.p;

	setPose(newPose);



}
	
Ogre::Vector3 UltimatePhysX3Actor::getFacingDir()
{
	PxTransform pose= nxActor->getGlobalPose();

	PxQuat initOri = pose.q;
	PxVec3 initDir = initOri.rotate(PxVec3(1,0,0));
	initDir.normalize();


	return Ogre::Vector3(initDir.x, initDir.y, initDir.z);
}


void UltimatePhysX3Actor::addForce(Ogre::Vector3 force)
{
	/*actor->setLinearVelocity(PxVec3(0,0,0));
	actor->setAngularVelocity(PxVec3(0,0,0));*/
	nxActor->addForce(PxVec3(force.x,force.y,force.z));
}

void UltimatePhysX3Actor::addTorque(Ogre::Vector3 torque)
{
	/*actor->setLinearVelocity(PxVec3(0,0,0));
	actor->setAngularVelocity(PxVec3(0,0,0));*/
	nxActor->addTorque(PxVec3(torque.x, torque.y, torque.z));
}


void UltimatePhysX3Actor::setUserData(void * data)
{
	userData = data;
	//nxActor->userData = data;
}

void * UltimatePhysX3Actor::getUserData(void)
{
	return userData;
	//return nxActor->userData;
}

void UltimatePhysX3Actor::disableGravity()
{
	nxActor->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, true);

}

void UltimatePhysX3Actor::setGroup(int i)
{
	PxSetGroup(*nxActor,i);

}

int UltimatePhysX3Actor::getGroup()
{
	return PxGetGroup(*nxActor);
}


void UltimatePhysX3Actor::setKinematic(bool isKinematic)
{
	kinematic = isKinematic;
	nxActor->setRigidDynamicFlag(PxRigidDynamicFlag::eKINEMATIC, isKinematic);
}

void UltimatePhysX3Actor::setPose(PxTransform pose)
{
	if(kinematic)
	{
		nxActor->setKinematicTarget(pose);
	}else
	{
		nxActor->setGlobalPose(pose);
	}

}